package kotlinx.coroutines.script.tes

import android.accessibilityservice.GestureDescription
import android.os.Build
import android.content.ClipboardManagerService
import sample.ui.Properties
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.script.C
import kotlinx.coroutines.script.Controller
import kotlinx.coroutines.script.XGesturePoint
import kotlinx.coroutines.withContext
import kotlin.math.min

object Accessibility {
    private var intercept = false
    val itc get() = intercept
    fun switchIntercept() {
        intercept = !intercept
    }
    val maxStrokeCount get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) GestureDescription.getMaxStrokeCount() else 10
    private var checkTs = 0L

    suspend fun playGestures(
        pointList: List<XGesturePoint>,
    ) = withContext(Dispatchers.Main) {
        if (intercept) {
            delay(1000)
            printLog { "Accessibility GesturesV2 intercepted" }
            return@withContext
        }

        val service = ClipboardManagerService.ins
        if (service == null) {
            analysisEvent("G3_playGestures_service_null")
            printLog { "Accessibility GesturesV2 playGestures service null" }
            return@withContext
        }
        val pList = pointList.filter { !it.propertiesError }
        if (pList.isEmpty()) {
            analysisEvent("G3_playGestures_pList_empty_[${pointList.size}#${pointList.lastOrNull()?.name}]")
            printLog { "Accessibility GesturesV2 playGestures pList empty [${pointList.size}#${pointList.lastOrNull()?.name}]" }
            return@withContext
        } else if (pList.size >= maxStrokeCount) {
            analysisEvent("G3_stroke_too_many_[${Properties.profession}][${pointList.lastOrNull()?.name}]")
            printLog { "Accessibility GesturesV2 stroke too many [${Properties.profession}][${pointList.lastOrNull()?.name}]" }
        }
        val finalList = pList.subList(0, min(pList.size, maxStrokeCount - 1))
        check()

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // Android8.0
            val builder = GestureDescription.Builder()
            var latestEnd = Long.MIN_VALUE
            for (point in finalList) {
                builder.addStroke(point.strokeDescription())
                latestEnd = kotlin.math.max(latestEnd, point.startDelay + point.invokingTime)
            }
            val description = builder.build()
            latestEnd = kotlin.math.max(latestEnd, 0)
            val name = pointList.joinToString("#")
            // 没有回掉可能卡死脚本?69版本卡死3个模拟器?原因是这个?.
            if (latestEnd > 10000) printLog { "Accessibility $name invoke time to long. $latestEnd" }

            val isDispatched: Boolean = service.dispatchGesture(description, null, null)
            delay(latestEnd + 30L.shake(10))

            if (name != C.V_SKILL_A
                    && name != C.V_SKILL_B
                    && name != C.V_SKILL_C
                    && name != C.V_SKILL_D
                    && name != C.V_SKILL_E) {
                printLog { "执行手势${if (!isDispatched) "[失败]" else ""} $name" }
            }
        }
    }

    private fun check() {
        if (System.currentTimeMillis() - checkTs > 598000) {
            if(Controller.isRunning) {
                if (Keys.isUsingCDKeyInfoActivating != 0) {
                    Controller.get().stop("卡密已失效")
                    Controller.isInvalid.postValue(true)
                    DiskLogUtils.saveToDisk()
                    repeat(3) {
                        printLog { "卡密已失效C" }
                        toast("卡密已失效")
                    }
                }
                checkTs = System.currentTimeMillis()
            }
        }
    }
}